package com.turing.draw.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.turing.common.util.*;
import com.turing.draw.client.procedure.ProcedureInnerService;
import com.turing.draw.client.reviewer.ReviewTaskInnerService;
import com.turing.draw.enums.FileStatusEnum;
import com.turing.draw.enums.OcrPageTaskStatusEnum;
import com.turing.draw.model.domain.FileTask;
import com.turing.draw.model.domain.OcrPageTask;
import com.turing.common.entity.ParseTableVO;
import com.turing.draw.model.vo.in.OcrResultVo;
import com.turing.draw.service.*;
import com.turing.draw.utils.TableUtil;
import com.turing.draw.vo.in.OcrResultEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class MergeOcrResultTask {

    @Value("${fdfs.domain}")
    private String MEDIA_PATH;

    @Autowired
    private OcrPageTaskService ocrPageTaskService;

    @Autowired
    private FileTaskService fileTaskService;

    @Autowired
    private DrawTaskService drawTaskService;

    @Autowired
    private CorrectOCRAnalyzeJsonService correctOCRAnalyzeJsonService;

    @Autowired
    private ReviewTaskInnerService reviewTaskInnerService;

    @Autowired
    private ProcedureInnerService procedureInnerService;

    @Autowired
    private FileImageService fileImageService;

    private static final Logger logger = LoggerFactory.getLogger(MergeOcrResultTask.class);

    @Async("ocrMergeTaskExecutor")
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean doMerge(OcrResultVo ocrResultVo, boolean isMergeTemplate){

        String taskSn = ocrResultVo.getTaskSn();
        FileTask fileTask = fileTaskService.getById(taskSn);
        AssertUtil.isEmpty(fileTask,"该taskSn下对应记录为空");
        Integer count = ocrPageTaskService.countFilesByTaskSnAndStatus(taskSn, OcrPageTaskStatusEnum.OCRTASKFINISHED.getCode());

        if(fileTask.getTotalPage().equals(count)){

            // update fileTask taskStatus
            if (isMergeTemplate) {
                fileTaskService.updateTaskByStatusAndId(taskSn,FileStatusEnum.MERGETEMPLATEPROCESSING.getCode());
            } else {
                fileTaskService.updateTaskByStatusAndId(taskSn,FileStatusEnum.OCRTASKFINISHED.getCode());
            }


            // check out all json text
            List<OcrPageTask> ocrPageTasks = ocrPageTaskService.lambdaQuery().select(OcrPageTask::getPageNo, OcrPageTask::getOcrJsonUrl)
                .eq(OcrPageTask::getTaskSn, taskSn)
                .eq(OcrPageTask::getOcrPageTaskStatus, OcrPageTaskStatusEnum.OCRTASKFINISHED.getCode())
                .eq(OcrPageTask::getIsDel, 0)
                .list().stream().sorted(Comparator.comparing(OcrPageTask::getPageNo))
                .collect(Collectors.toList());

            JSONArray mergedJsonArray = new JSONArray();

            StringBuilder cleanBuilder = new StringBuilder();
            for (OcrPageTask ocrPageTask : ocrPageTasks) {

                String JSONText = FileUtils.loadJson(MEDIA_PATH + ocrPageTask.getOcrJsonUrl());

                JSONArray jsonArray = JSONArray.parseArray(JSONText.trim());
                if(Tools.isNotEmpty(jsonArray)){
                    for (Object obj : jsonArray) {
                        OcrResultEntity.PageEntity pageEntity = JSONObject.parseObject(obj.toString(),OcrResultEntity.PageEntity.class);
                        List<OcrResultEntity.PageEntity.LineEntity> lineList = pageEntity.getLineList();
                        if(Tools.isNotEmpty(lineList)){
                            for (OcrResultEntity.PageEntity.LineEntity lineEntity : lineList) {
                                String objContent = lineEntity.getObjContent();
                                if(StringUtils.isNotEmpty(objContent)){
                                    cleanBuilder.append(objContent);
                                }
                            }
                        }
                    }
                }

                mergedJsonArray.addAll(jsonArray);
                ocrPageTaskService.deleteByOcrPageTaskSn(ocrPageTask.getOcrPageTaskSn());
            }

            List<ParseTableVO> tables = new ArrayList<>();
            try{
                logger.debug("===========> 开始进行表格处理 <===============");
                tables = TableUtil.handleTables(mergedJsonArray);
                logger.debug("===========> 表格处理完成 <===============");
            }catch (Exception e) {
                logger.error("表格数据处理失败");
                e.printStackTrace();
            }

            String tableJsonUrl = FdfsUtils.uploadBytes(JSONArray.toJSONString(tables));
            String cleanText = cleanBuilder.toString();
            String cleanTextUrl = FdfsUtils.uploadBytes(cleanText);
            String originalJsonUrl = FdfsUtils.uploadBytes(mergedJsonArray.toJSONString());
            String mergedJSONUrl = fileTaskService.uploadMergedOcrResult(taskSn, mergedJsonArray,fileImageService);

            boolean update = fileTaskService.saveJSONTextByTaskSn(taskSn,mergedJSONUrl,originalJsonUrl,cleanTextUrl,tableJsonUrl);
            logger.info("merge ocr result,update file task status,taskSn is:"+taskSn+",status is:"+update);

            // sweep page json text
            ocrPageTasks.forEach(
                opt->{
                    FdfsUtils.delete_file(opt.getOcrJsonUrl());
                }
            );

            // sweep ocr fileTask record
            int removed = ocrPageTaskService.removeTasksByTaskSn(taskSn);
            logger.info("sweep ocr fileTask record,taskSn is:"+taskSn+",status is:"+removed);

            fileTaskService.doRuleProcess(fileTask);

            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        List<ParseTableVO> tables = new ArrayList<>();
        String json = FileUtils.readFile("C:\\Users\\98637\\Desktop\\temp_1669254091999.json");
        JSONArray array = JSONArray.parseArray(json);
        tables = TableUtil.handleTables(array);

    }
}
